package com.hzit.aspect;

import com.hzit.annotation.RequiresPermissions;
import com.hzit.exception.NotAccessPermissionException;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextListener;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;

/**
 * 类名：
 * 作者：WF
 * 功能：
 */
@Aspect
@Component
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class PreAuthorizeAspect {

	//写法一：
	@Around("@annotation(permissions)")
	public Object innerAround(ProceedingJoinPoint point, RequiresPermissions permissions) throws Throwable{
		String[] value = permissions.value();
		System.out.println("你的访问权限是：" + Arrays.toString(value));
		ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
		HttpServletRequest request = requestAttributes.getRequest();
		ServletContext servletContext = request.getServletContext();
		List<String> permissionList = (List<String>) servletContext.getAttribute("permissions");
		boolean b = hasPermission(Arrays.asList(value), permissionList);
		if(b){
			System.out.println("环绕通知---》前置代码[方案一]");
			return point.proceed();
		}
		throw new NotAccessPermissionException("对不起，你无权访问此方法！[方案一]");
	}

	//写法二 ：
	// public static final String POINTCUT_SIGN = " @annotation(com.hzit.annotation.RequiresPermissions)";
	// @Pointcut(POINTCUT_SIGN)
	// public void pc(){
	// }
	// @Around("pc()")
	// public Object innerAround(ProceedingJoinPoint point) throws Throwable{
	// 	MethodSignature signature = (MethodSignature) point.getSignature();
	// 	Method method = signature.getMethod();
	// 	RequiresPermissions annotation = method.getAnnotation(RequiresPermissions.class);
	// 	String[] value = annotation.value();
	// 	List<String> myPermissions = Arrays.asList(value);
	// 	System.out.println("(版本二)你的访问权限是：" + Arrays.toString(value));
	// 	ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
	// 	HttpServletRequest request = attributes.getRequest();
	// 	ServletContext servletContext = request.getServletContext();
	// 	List<String> permissions = (List<String>) servletContext.getAttribute("permissions");
	// 	boolean hasPermission = hasPermission(myPermissions,permissions);
	// 	if(hasPermission){
	// 		System.out.println("(版本二)环绕通知---》前置代码");
	// 		return point.proceed();
	// 	}
	// 	throw new NotAccessPermissionException("对不起，你无权访问此方法！");
	//
	// }

	/**
	 *
	 * @param myPermissions  我在控制器指定的权限串
	 * @param permissions    当前用户所有的权限集合串
	 * @return
	 */
	private boolean hasPermission(List<String> myPermissions, List<String> permissions) {
		for (String per : myPermissions) {
			if(permissions.contains(per)){
				return true;
			}
		}
		return false;
	}
}
